package com.example.book.generator.controller;

import com.example.book.common.utils.Constants;
import com.example.book.common.utils.DateUtils;
import com.example.book.generator.entity.Table;
import com.example.book.generator.utils.*;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.*;

/**
 * @author haocj
 * @date
 */
public class Generating {


    private String packageName;
    private String author;

    public Generating(String packageName, String author) {
        this.packageName = packageName;
        this.author = author;
    }

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    private DataType dataType = new DataType();
    private Hump hump = new Hump();
    private Folder folder = new Folder();

    private static final String ENTITY = ".entity";
    private static final String DAO = ".dao";
    private static final String SERVICE = ".service";
    private static final String CONTROLLER = ".controller";
    private static final String MAPPER = ".mapper";

    private static final String ENTITY_JAVA = ".java";
    private static final String DAO_JAVA = "Dao.java";
    private static final String SERVICE_JAVA = "Service.java";
    private static final String CONTROLLER_JAVA = "Controller.java";
    private static final String MAPPER_XML = "Mapper.xml";


    public Integer builder(String tableName, List<Table> list) {

        String className = new Hump().toCapitalizeCamelCase(tableName);

        if (list.size() <= 0) {
            return Constants.GENERRATOR_STATUS_0;
        }

        try {
            List<Object> domain = new ArrayList<>();
            List<Object> mapper = new ArrayList<>();

            for (int i = 0; i < list.size(); i++) {
                domain.add(new Entity(hump.toCamelCase(list.get(i).getColumnName()), dataType.getNewDataType(list.get(i).getDataType()), list.get(i).getColumnComment()));
                mapper.add(new Xmls(list.get(i).getColumnName(), list.get(i).getDataType().toUpperCase(), dataType.getNewDataType(list.get(i).getDataType()), hump.toCamelCase(list.get(i).getColumnName())));
            }

            Map<String, Object> root = new HashMap<>();
            root.put("packageName", packageName);
            root.put("className", className);
            root.put("className1", hump.toCamelCase(tableName));
            root.put("entity", domain);
            root.put("author", author);
            root.put("createTime", DateUtils.formatDate(new Date()));

            Map<String, Object> xml = new HashMap<>();
            xml.put("packageName", packageName);
            xml.put("className", className);
            xml.put("className1", hump.toCamelCase(tableName));
            xml.put("xml", mapper);
            xml.put("table", tableName);
            xml.put("m", "{");
            xml.put("n", "}");
            xml.put("o", "<!--");
            xml.put("p", "-->");

            int i = template(root, xml, packageName, className);
            if (i == 0) {
                return Constants.SUCCESS;
            } else {
                return Constants.GENERRATOR_STATUS_2;
            }

        } catch (Exception e) {
            e.printStackTrace();
            // 系统异常返回值
            return Constants.GENERRATOR_STATUS_2;
        }
    }

    /**
     * 文件生成实现
     *
     * @param domain
     * @param xml
     * @param packageName
     * @param className
     */
    private int template(Map<String, Object> domain, Map<String, Object> xml, String packageName, String className) {

        String entityPath = folder.folder(packageName + ENTITY);
        String daoPath = folder.folder(packageName + DAO);
        String servicePath = folder.folder(packageName + SERVICE);
        String webPath = folder.folder(packageName + CONTROLLER);
        String xmlPath = folder.folder(packageName + MAPPER);

        Template template = null;
        StringWriter writer = null;
        String str = null;

        String path = Generating.class.getResource("/").getPath() + "templates/gen";
        System.out.println(path);
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
        try {
            configuration.setDirectoryForTemplateLoading(new File(path));

            template = configuration.getTemplate("/entity.ftl");
            writer = new StringWriter();
            template.process(domain, writer);
            str = className + ENTITY_JAVA;
            FileWriter fileWriter = new FileWriter(entityPath + "/" + str, false);
            fileWriter.write(String.valueOf(writer));
            fileWriter.close();

            template = configuration.getTemplate("/dao.ftl");
            writer = new StringWriter();
            template.process(domain, writer);
            str = className + DAO_JAVA;
            FileWriter fileWriter1 = new FileWriter(daoPath + "/" + str, false);
            fileWriter1.write(String.valueOf(writer));
            fileWriter1.close();

            template = configuration.getTemplate("/service.ftl");
            writer = new StringWriter();
            template.process(domain, writer);
            str = className + SERVICE_JAVA;
            FileWriter fileWriter2 = new FileWriter(servicePath + "/" + str, false);
            fileWriter2.write(String.valueOf(writer));
            fileWriter2.close();

            template = configuration.getTemplate("/web.ftl");
            writer = new StringWriter();
            template.process(domain, writer);
            str = className + CONTROLLER_JAVA;
            FileWriter fileWriter3 = new FileWriter(webPath + "/" + str, false);
            fileWriter3.write(String.valueOf(writer));
            fileWriter3.close();

            template = configuration.getTemplate("/xml.ftl");
            writer = new StringWriter();
            template.process(xml, writer);
            str = className + MAPPER_XML;
            FileWriter fileWriter4 = new FileWriter(xmlPath + "/" + str, false);
            fileWriter4.write(String.valueOf(writer));
            fileWriter4.close();

        } catch (IOException e) {
            e.printStackTrace();
            return Constants.ERROR;
        } catch (TemplateException e) {
            e.printStackTrace();
            return Constants.ERROR;
        }
        return Constants.SUCCESS;
    }

}
